local Widget = require 'widgets/widget'
local Image = require 'widgets/image'
local Text = require 'widgets/text'

---输入0~255的rgb,和0~1的a
---@param r integer
---@param g integer
---@param b integer
---@param a nil|number
---@return number
---@return number
---@return number
---@return nil|number
---@nodiscard
local function tint_decimal(r,g,b,a)
    if a then
        return r/255,g/255,b/255,a
    end
    return r/255,g/255,b/255
end

---comment
---@param str_num string
local function roundWithTwoDecimal(str_num)
    return string.format('%.2f',str_num)
end

local ymh_exp = Class(Widget, function (self)
    Widget._ctor(self, "ymh_exp")

    -- 背景
    self.w = 260
    self.h = 150

    ---@type widget_image
    self.bg = self:AddChild(Image("images/global.xml", "square.tex"))
    self.bg:SetHAnchor(ANCHOR_MIDDLE)
    self.bg:SetVAnchor(ANCHOR_MIDDLE)
    self.bg:SetSize(self.w,self.h)
    self.bg:SetPosition(0,200)
    self.bg:SetTint(tint_decimal(220,114,28,1))

    -- 边框宽度
    local frame_width = 6
    self.bg2 = self.bg:AddChild(Image("images/global.xml", "square.tex"))
    self.bg2:SetSize(self.w-frame_width,self.h-frame_width)
    self.bg2:SetTint(tint_decimal(30,30,30,1))

    -- 凹陷
    local deep_frame = 2
    self.bg3 = self.bg:AddChild(Image("images/global.xml", "square.tex"))
    self.bg3:SetSize(self.w-frame_width-deep_frame,self.h-frame_width-deep_frame)
    self.bg3:SetTint(tint_decimal(48,48,48,1))

    -- 接下来做一个类似表格一样的东西,二元表,统一对齐
    local tbl_first_pos_x = - (self.w/2 - frame_width - deep_frame)
    local tbl_pos_y = self.h/2 - frame_width - deep_frame
    local line_spacing = 4

    -- 为表格排序
    local rules = {
        'exp',
        'lv',
        'atk',
        'regen',
    }

    ---@type table<string,{info: widget_text, data:widget_text}>
    self.data = {}

    local single_font_w,single_font_h = 10,20 -- 字体宽高
    local max_string_len = 7 -- info最大字符数
    local font_size = single_font_h*1.3 -- 字体大小
    local top_margin_fix = 18 -- info顶部偏移量


    self.data.exp = {}
    self.data.exp.info = self.bg:AddChild(Text(BODYTEXTFONT,font_size,'经验值: ',{1,1,1,1}))
    self.data.lv = {}
    self.data.lv.info = self.bg:AddChild(Text(BODYTEXTFONT,font_size,'等级: ',{1,1,1,1}))
    self.data.atk = {}
    self.data.atk.info = self.bg:AddChild(Text(BODYTEXTFONT,font_size,'罡拳增伤: ',{1,1,1,1}))
    self.data.regen = {}
    self.data.regen.info = self.bg:AddChild(Text(BODYTEXTFONT,font_size,'每秒回血: ',{1,1,1,1}))


    local exp_bar_w,exp_bar_h = 150,20
    self.inter_bar_w = 144
    self.inter_bar_h = 14
    local inter_bar_offset = 3

    ---@type widget_image
    self.data.exp.bar = self.bg:AddChild(Image("images/global.xml", "square.tex"))
    self.data.exp.bar:SetSize(exp_bar_w,exp_bar_h)
    self.data.exp.bar:SetTint(tint_decimal(0,0,0,1))
    self.data.exp.bar:SetHRegPoint(ANCHOR_LEFT)

    self.data.exp.bar.realbar = self.data.exp.bar:AddChild(Image("images/global.xml", "square.tex"))
    self.data.exp.bar.realbar:SetSize(self.inter_bar_w*0,self.inter_bar_h)
    self.data.exp.bar.realbar:SetTint(tint_decimal(30,237,239,1))
    self.data.exp.bar.realbar:SetHRegPoint(ANCHOR_LEFT)
    self.data.exp.bar.realbar:SetPosition(inter_bar_offset,0)

    ---@type widget_text
    self.data.exp.bar.exp_data = self.data.exp.bar:AddChild(Text(NUMBERFONT,font_size-5,'0/100',{1,1,1,1}))
    self.data.exp.bar.exp_data:SetPosition(self.inter_bar_w/2,0)

    self.data.lv.data = self.bg:AddChild(Text(BODYTEXTFONT,font_size,' ',{1,1,1,1}))
    self.data.atk.data = self.bg:AddChild(Text(BODYTEXTFONT,font_size,' ',{1,1,1,1}))
    self.data.regen.data = self.bg:AddChild(Text(BODYTEXTFONT,font_size,' ',{1,1,1,1}))

    local tbl_second_pos_x = tbl_first_pos_x+single_font_w*max_string_len
    for i,v in ipairs(rules) do
        if self.data[v] then
            if self.data[v].info then
                self.data[v].info:SetRegionSize(single_font_w*max_string_len,single_font_h)
                self.data[v].info:SetVAlign(ANCHOR_MIDDLE)
                self.data[v].info:SetHAlign(ANCHOR_LEFT)
                self.data[v].info:SetPosition(tbl_first_pos_x+single_font_w*max_string_len/2,tbl_pos_y - top_margin_fix - (single_font_h+line_spacing)*(i-1))
            end
            if self.data[v].data then
                self.data[v].data:SetRegionSize(single_font_w*max_string_len,single_font_h)
                self.data[v].data:SetVAlign(ANCHOR_MIDDLE)
                self.data[v].data:SetHAlign(ANCHOR_LEFT)
                self.data[v].data:SetPosition(tbl_second_pos_x + single_font_w*max_string_len/2,tbl_pos_y - top_margin_fix - (single_font_h+line_spacing)*(i-1))
            end
            if v == 'exp' then
                if self.data[v].bar then
                    self.data[v].bar:SetPosition(tbl_second_pos_x ,tbl_pos_y - top_margin_fix - (single_font_h+line_spacing)*(i-1))
                end
            end
        end
    end

    local fade = .1
    local panel_last_time = 5

    ThePlayer:ListenForEvent('ymh_lv_exp_cur_change',function ()
        self:SetFadeAlpha(1)
        self:Show()
        -- TheWorld:DoPeriodicTask(.2,function ()
        --     fade = math.min(1,fade+.1)
        --     self:SetFadeAlpha(fade)
        -- end)
        if TheWorld.taskintime_ymh_lv_cancel then
            TheWorld.taskintime_ymh_lv_cancel:Cancel()
            TheWorld.taskintime_ymh_lv_cancel = nil
        end
        TheWorld.taskintime_ymh_lv_cancel = TheWorld:DoTaskInTime(panel_last_time,function ()
            self:Hide()
        end)
        self:UpdateAll()
    end)

    TheWorld:DoTaskInTime(0,function()
        self:UpdateAll()
    end)

    self:Hide()
    
end)

function ymh_exp:UpdateAll()
    local player = ThePlayer
    if player.replica.ymh_lv then
        local lv = player.replica.ymh_lv:get_lv_cur() or 0
        local exp_cur = player.replica.ymh_lv:get_exp_cur() or 0
        local exp_cur_max = player.replica.ymh_lv:get_exp_cur_max() or 0
        self:SetLv(lv)
        local dmg = math.min(10000,math.pow(lv,2))
        self:SetAtk(dmg)
        local regen = math.min(lv * TUNING.MOD_YUEMIHENG.AVATAR.YUEMIHENG.EXP.AUTOREGEN_PER,TUNING.MOD_YUEMIHENG.AVATAR.YUEMIHENG.EXP.AUTOREGEN_PER_MAX)
        self:SetRegen(regen)
        self:SetExp(exp_cur,exp_cur_max)
    end
end

function ymh_exp:SetLv(lv)
    self.data.lv.data:SetString(tostring(lv))
end

function ymh_exp:SetAtk(dmg)
    self.data.atk.data:SetString(tostring(dmg))
end

function ymh_exp:SetRegen(delta)
    self.data.regen.data:SetString(tostring(delta))
end

function ymh_exp:SetExp(cur,total)
    if cur and total then
        local exp_bar = roundWithTwoDecimal(tostring(cur)) .. '/' .. tostring(total)
        self.data.exp.bar.exp_data:SetString(exp_bar)

        local num_cur = tonumber(cur)
        local num_total = tonumber(total)
        if num_total > 0 then
            local rate = num_cur / num_total
            self.data.exp.bar.realbar:SetSize(self.inter_bar_w*rate,self.inter_bar_h)
        end
    end
end


return ymh_exp